#coding=utf-8
from collections import deque

class Node(object):
    """节点类"""
    def __init__(self, elem=-1, lchild=None, rchild=None):
        self.elem = elem
        self.lchild = lchild
        self.rchild = rchild


class Tree(object):
    """树类"""
    def __init__(self):
        self.root = Node()
        self.myQueue = []

    def add(self, elem):
        """为树添加节点"""
        node = Node(elem)
        if self.root.elem == -1:  # 如果树是空的，则对根节点赋值
            self.root = node
            self.myQueue.append(self.root)
        else:
            treeNode = self.myQueue[0]  # 此结点的子树还没有齐。
            if treeNode.lchild == None:
                treeNode.lchild = node
                self.myQueue.append(treeNode.lchild)
            else:
                treeNode.rchild = node
                self.myQueue.append(treeNode.rchild)
                self.myQueue.pop(0)  # 如果该结点存在右子树，将此结点丢弃。


    def front_digui(self, root):
        """利用递归实现树的先序遍历"""
        if root == None:
            return
        print(root.elem)
        self.front_digui(root.lchild)
        self.front_digui(root.rchild)


    def middle_digui(self, root):
        """利用递归实现树的中序遍历"""
        if root == None:
            return
        self.middle_digui(root.lchild)
        print(root.elem)
        self.middle_digui(root.rchild)


    def later_digui(self, root):
        """利用递归实现树的后序遍历"""
        if root == None:
            return
        self.later_digui(root.lchild)
        self.later_digui(root.rchild)
        print(root.elem)


    def front_stack(self, root):
        """利用堆栈实现树的先序遍历"""
        if root == None:
            return
        myStack = []
        node = root
        while node or myStack:
            while node:                     #从根节点开始，一直找它的左子树
                print(node.elem)
                myStack.append(node)
                node = node.lchild
            node = myStack.pop()            #while结束表示当前节点node为空，即前一个节点没有左子树了
            node = node.rchild                  #开始查看它的右子树


    def middle_stack(self, root):
        """利用堆栈实现树的中序遍历"""
        if root == None:
            return
        myStack = []
        node = root
        while node or myStack:
            while node:                     #从根节点开始，一直找它的左子树
                myStack.append(node)
                node = node.lchild
            node = myStack.pop()            #while结束表示当前节点node为空，即前一个节点没有左子树了
            print(node.elem)
            node = node.rchild                  #开始查看它的右子树


    def later_stack(self, root):
        """利用堆栈实现树的后序遍历"""
        if root == None:
            return
        myStack1 = []
        myStack2 = []
        node = root
        myStack1.append(node)
        a = [root.lchild]
        b =a.pop()
        deq = deque([root,root])
        while myStack1:                   #这个while循环的功能是找出后序遍历的逆序，存在myStack2里面
            node = myStack1.pop()
            if node.lchild:
                myStack1.append(node.lchild)
            if node.rchild:
                myStack1.append(node.rchild)
            myStack2.append(node)
        while myStack2:                         #将myStack2中的元素出栈，即为后序遍历次序
            print(myStack2.pop().elem)


    def level_queue(self, root):
        """利用队列实现树的层次遍历"""
        if root == None:
            return
        res = []
        myQueue = []
        node = root
        myQueue.append(node)
        while myQueue:
            a =[]
            l = len(myQueue)
            for i in range(l):
                node = myQueue.pop(0)
                a.append(node.elem)
                if node.lchild != None:
                    myQueue.append(node.lchild)
                if node.rchild != None:
                    myQueue.append(node.rchild)
            res.append(a)
        print(res)

    def levelOrderBottom(self, root):
        queue = []                                                  # 结果列表
        cur = [root]                                                # 接下来要循环的当前层节点，存的是节点
        while cur:                                                  # 当前层存在结点时
            cur_layer_val = []                                      # 初始化当前层结果列表为空，存的是val
            next_layer_node = []                                    # 初始化下一层结点列表为空
            for node in cur:                                        # 遍历当前层的每一个结点
                if node:                                            # 如果该结点不为空，则进行记录
                    cur_layer_val.append(node.elem)                  # 将该结点的值加入当前层结果列表的末尾
                    next_layer_node.extend([node.lchild, node.rchild]) # 将该结点的左右孩子结点加入到下一层结点列表
            if cur_layer_val:                                       # 只要当前层结果列表不为空
                queue.insert(0, cur_layer_val)                      # 则把当前层结果列表插入到队列首端
            cur = next_layer_node                                   # 下一层的结点变成当前层，接着循环
        print(queue)                                                # 返回结果队列

    def isBalanced(self, root) :
        if not root: return True
        return abs(self.depth(root.lchild) - self.depth(root.rchild)) <= 1 and \
                self.isBalanced(root.lchild) and self.isBalanced(root.rchild)

    def depth(self, root):
        if not root: return 0
        return max(self.depth(root.lchild), self.depth(root.rchild)) + 1




if __name__ == '__main__':
    """主函数"""
    elems = range(10)           #生成十个数据作为树节点
    tree = Tree()          #新建一个树对象
    for elem in elems:
        tree.add(elem)           #逐个添加树的节点


    print('队列实现层次遍历:')
    tree.level_queue(tree.root)
    #
    # print('\n\n递归实现先序遍历:')
    # tree.front_digui(tree.root)
    # print('\n递归实现中序遍历:' )
    # tree.middle_digui(tree.root)
    print('\n递归实现后序遍历:')
    tree.later_digui(tree.root)
    #
    # print('\n\n堆栈实现先序遍历:')
    # tree.front_stack(tree.root)
    # print('\n堆栈实现中序遍历:')
    # tree.middle_stack(tree.root)
    # print('\n堆栈实现后序遍历:')
    # tree.later_stack(tree.root)

    print('队列实现后序层次遍历:')
    tree.levelOrderBottom(tree.root)

    print(tree.isBalanced(tree.root))